package cn.fuxi2022.module.file;

import cn.fuxi2022.core.exception.SmartGroupException;
import cn.fuxi2022.model.resp.R;
import cn.fuxi2022.qiniu.utils.QiNiuUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@RestController
@RequestMapping("/file")
public class FileUploadAndDelete {

    /**
     * 判断文件大小
     *
     * @param len  文件长度
     * @param size 限制大小
     * @param unit 限制单位（B,K,M,G）
     * @return true文件符合大小 false文件过大
     */
    public static boolean checkFileSize(Long len, int size, String unit) {
        double fileSize;
        switch (unit.toUpperCase()) {
            case "B":
                fileSize = (double) len;
                break;
            case "K":
                fileSize = (double) len / 1024;
                break;
            case "M":
                fileSize = (double) len / 1048576;
                break;
            case "G":
                fileSize = (double) len / 1073741824;
                break;
            default:
                // 未指定，就使用默认的K
                fileSize = (double) len / 1048576;
        }
        return !(fileSize > size);
    }

    private String check(MultipartFile file) {
        // 判断上传的文件是否为空文件
        if (ObjectUtils.isEmpty(file) || file.isEmpty()) {
            throw new SmartGroupException("上传的文件不能为空");
        }

        // 原始文件名称
        String fileName = file.getOriginalFilename();

        // 解析到文件后缀，判断是否合法
        int index = fileName.lastIndexOf(".");
        String suffix = null;
        if (index == -1 || (suffix = fileName.substring(index + 1)).isEmpty()) {
            throw new SmartGroupException("文件后缀不能为空");
        }

        // 允许上传的文件后缀列表
        Set<String> allowSuffix = new HashSet<>(Arrays.asList("jpg", "jpeg", "png"));
        if (!allowSuffix.contains(suffix.toLowerCase())) {
            throw new SmartGroupException("非法的文件，不允许的文件类型：" + suffix + "，需要上传图片类型的文件");
        }

        // 文件不大于2M
        if (!checkFileSize(file.getSize(), 2, "M")) {
            throw new SmartGroupException("文件过大，上传的文件不能大于2M");
        }

        return "." + suffix.toLowerCase();
    }

    /**
     * 上传文件，供小程序内部使用
     *
     * @param file 文件
     * @return 文件上传成功后的链接
     */
    @PostMapping("/upload/image/config")
    public R uploadConfig(MultipartFile file) {
        // 注意：后端controller接口接收的Multipart变量必须为file，不然springmvc不自动封装
        String type = check(file);

        String url;
        try {
            url = QiNiuUtils.uploadFileFromQiniu(file.getBytes(), QiNiuUtils.IMAGE_CONFIG_PATH, type);
        } catch (IOException e) {
            e.printStackTrace();
            throw new SmartGroupException("文件上传失败");
        }
        return R.ok().put("path",url);
    }

    /**
     * 上传文件，供用户使用
     *
     * @param file 文件
     * @return 文件上传成功后的链接
     */
    @PostMapping("/upload/image")
    public R upload(MultipartFile file) {
        String type = check(file);

        String url;
        try {
            url = QiNiuUtils.uploadFileFromQiniu(file.getBytes(), QiNiuUtils.IMAGE_USER_PATH, type);
        } catch (IOException e) {
            e.printStackTrace();
            throw new SmartGroupException("文件上传失败");
        }
        return R.ok().put("path",url);
    }

    /**
     * 删除文件，危险方法，不建议暴露，测试使用
     *
     * @param map 要删除的文件url
     * @return 成功true 失败false
     */
    @DeleteMapping("/delete")
    public R delete(@RequestBody Map<String, String> map) {
        String url = map.get("url");
        // QiNiuUtils.deleteFileFromQiniu(url);
        return R.ok().data(true);
    }

}
